package org.infoset.xml.memory;

import java.util.*;
import java.net.*;
import org.infoset.xml.*;

public class MemoryNameTable implements NameTable {

   static MemoryNameTable defaultTable = new MemoryNameTable();

   Map unqualified;
   Map namespaceLocals;
   Map namespaces;

   public static NameTable getDefaultNameTable() {
      return defaultTable;
   }

   public MemoryNameTable() {
      this.unqualified = new HashMap();
      this.namespaceLocals = new HashMap();
      this.namespaces = new HashMap();
   }

   public URI createNamespace(String namespace) 
      throws URISyntaxException
   {
      // TODO: implement
      if (namespace.equals("NO:NAMESPACE")) {
         throw new IllegalArgumentException("NO:NAMESPACE is reserved for internal use.");
      }
      URI uri = (URI)namespaces.get(namespace);
      if (uri==null) {
         uri = new URI(namespace);
         synchronized (namespaces) {
            namespaces.put(namespace,uri);
         }
      }
      return uri;
   }

   /*
   public URI createNamespace(char [] buffer, int start, int length) 
      throws MalformedURIException
   {
      // TODO: implement
      return new URI(new String(buffer,start,length));
   }
   */

   /*
   public Name createName(URI namespace,char [] buffer, int start, int length) {
      // TODO: implement
      return new Name(namespace,new String(buffer,start,length));
   }
   */

   public Name createName(URI namespace,String localName) {
      Map map = (Map)namespaceLocals.get(namespace);
      if (map==null) {
         map = new HashMap();
         synchronized (namespaceLocals) {
            namespaceLocals.put(namespace,map);
         }
      }
      Name nm = (Name)map.get(localName);
      if (nm==null) {
         nm = new Name(namespace,localName);
         synchronized (map) {
            map.put(localName,nm);
         }
      }
      return nm;
   }

   /*
   public Name createName(char [] buffer, int start, int length) {
      // TODO: implement
      return new Name(new String(buffer,start,length));
   }
   */

   public Name createName(String localName) {
      Name nm = (Name)unqualified.get(localName);
      if (nm==null) {
         nm = new Name(localName);
         synchronized (unqualified) {
            unqualified.put(localName,nm);
         }
      }
      return nm;
   }

}
